import React, { Component } from 'react';
import { connect } from 'dva';
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
import { NAME_RULE, CODE_RULE } from '@/Constants/rules';
import { Card, Form, Modal, Input, Select, message } from 'antd';
import api from '@/api';
import { trim } from '@/utils/utils';
import styles from './Org.less';
import OrgTree from './OrgTree';
import OrgInfo from './OrgInfo';

const FormItem = Form.Item;
const Option = Select.Option;
const TextArea = Input.TextArea;

@connect(({ org, loading }) => ({
  orgTree: org.orgTree,
  orgType: org.orgType,
  submitLoading: loading.effects['org/saveOrgTree']
}))
@Form.create()
class Org extends Component {
  constructor(props) {
    super(props);
    this.state = {
      action: '',
      modalVisible: false,
      selectedKeys: [],
      parentNode: {},
      currentNode: {},
    };
    this.orgTreeRef = React.createRef();
  }

  componentDidMount() {
    const { dispatch } = this.props;
    dispatch({
      type: 'org/queryOrgType',
    });
    this.queryOrgTree().then(res => {
      this.setState({
        currentNode: this.props.orgTree[0],
      });
    });
  }

  getNodeInfoFromTree = (tree, id) => {
    let nodeInfo = Object.create(null);
    let treeLoop = tree => {
      for (var i = 0; i < tree.length; i++) {
        if (tree[i].id === id) {
          nodeInfo = tree[i];
          break;
        } else if (tree[i].children) {
          treeLoop(tree[i].children);
        }
      }
    };
    treeLoop(tree);
    return nodeInfo;
  };

  handleDropdown = item => {
    setTimeout(() => {
      this.setState({
        selectedKeys: [item.id],
      });
    });
  };

  handleTreeSelect = (selectedKeys, e) => {
    this.setState({
      selectedKeys,
      currentNode: e.node.props.dataRef,
    });
  };

  queryOrgInfo = id => {
    const { dispatch } = this.props;
    return dispatch({
      type: 'org/queryOrgInfo',
      payload: {
        pathParams: { id },
      },
    });
  };

  handleModalVisible = () => {
    this.setState({
      modalVisible: false,
    });
  };

  queryOrgTree = () => {
    const { dispatch } = this.props;
    return dispatch({
      type: 'org/queryOrgTree',
    });
  };

  createOrg = params => {
    const { dispatch } = this.props;
    return dispatch({
      type: 'org/create',
      payload: {
        data: params,
      },
    });
  };

  updateOrg = params => {
    const { dispatch } = this.props;
    return dispatch({
      type: 'org/update',
      payload: {
        data: params,
      },
    });
  };

  deleteOrg = () => {
    Modal.confirm({
      title: '删除',
      content: '将删除所选组织及下级组织，是否确定删除？',
      okText: '确定',
      cancelText: '取消',
      onOk: async () => {
        const { dispatch, orgTree } = this.props;
        let res = await dispatch({
          type: 'org/delete',
          payload: {
            pathParams: { id: this.state.selectedKeys[0] },
          },
        });
        if (res.errorCode === 0) {
          message.success('删除成功');
          let parentNodeInfo = this.getNodeInfoFromTree(orgTree, this.state.currentNode.parentId);
          let children = parentNodeInfo.children;
          let index = children.map(node => node.id).indexOf(this.state.selectedKeys[0]);
          let currentNode =
            index > 0 ? children[index - 1] : children.length > 1 ? children[1] : parentNodeInfo;
          dispatch({
            type: 'org/saveOrgTree',
            payload: res.data,
          });

          this.setState({
            currentNode: currentNode,
            selectedKeys: [currentNode.id],
          });
        }
      }
    });
  };

  okHandle = () => {
    const { dispatch, form, submitLoading } = this.props;
    const { action, selectedKeys, currentNode } = this.state;
    if (submitLoading) return
    form.validateFields(async (err, fieldsValue) => {
      if (err) return;
      let res = Object.create(null);
      if (action === 'create') {
        res = await this.createOrg({
          rootId: currentNode.rootId,
          parentId: selectedKeys[0],
          ...fieldsValue,
        });
      } else {
        res = await this.updateOrg({
          rootId: currentNode.rootId,
          id: selectedKeys[0],
          ...fieldsValue,
        });
      }
      if (res.errorCode === 0) {
        this.setState({
          modalVisible: false,
          currentNode: {
            ...currentNode,
            ...fieldsValue,
          },
        });
        if (action === 'create') {
          this.orgTreeRef.current.changeExpandedKeys([this.state.currentNode.id]);
          let nodeInfo = this.getNodeInfoFromTree(res.data, selectedKeys[0]);
          let currentNode = nodeInfo.children[nodeInfo.children.length - 1];
          this.setState({
            currentNode: currentNode,
            selectedKeys: [currentNode.id],
          });
        }
        message.success(action === 'create' ? '添加成功' : '修改成功');
        dispatch({
          type: 'org/saveOrgTree',
          payload: res.data,
        });
      }
    });
  };

  handleMenuClick = e => {
    switch (e.key) {
      case '0':
        this.showOrgModal('create');
        break;
      case '1':
        this.showOrgModal('modify');
        break;
      case '2':
        this.deleteOrg();
        break;
      default:
        break;
    }
  };

  showOrgModal = action => {
    let parentNode = Object.create(null);
    try {
      const { currentNode } = this.state;
      let parentId = action === 'create' ? currentNode.id : currentNode.parentId;
      parentId && (parentNode = this.getNodeInfoFromTree(this.props.orgTree, parentId));
    } catch (error) {
      console.log(`showUpdateOrg: ${error}`);
    }

    this.setState({
      modalVisible: true,
      parentNode,
      action,
    });
  };

  isDisabledType = typeId => {
    let isDisabled = false;
    try {
      const { action, currentNode, parentNode } = this.state;

      if (typeId < parentNode.structType) {
        isDisabled = true;
      }

      let children = currentNode.children;
      if (children && action === 'modify') {
        if (typeId > Math.min(...children.map(node => node.structType))) {
          isDisabled = true;
        }
      }
    } catch (error) {
      console.log(`isDisabledType: ${error}`);
    }
    return isDisabled;
  };

  handleCreateIconClick = item => {
    setTimeout(() => {
      this.setState({
        selectedKeys: [item.id],
      });
    });

    this.setState({
      modalVisible: true,
      action: 'create',
      parentNode: item,
    });
  };

  checkName = (rule, value, callback) => {
    if (value === '' || value == null) {
      callback('');
      return;
    }

    const { currentNode, selectedKeys, action } = this.state;
    let params = {
      pathParams: {
        parentId: '',
        id: '',
        rootId: currentNode.rootId,
      },
      queryParams: {
        name: value,
      },
    };
    if (action === 'create') {
      params.pathParams.id = '0';
      params.pathParams.parentId = selectedKeys[0];
    } else {
      params.pathParams.id = selectedKeys[0];
      params.pathParams.parentId = currentNode.parentId;
    }

    api.org.checkName(params).then(res => {
      if (!res.data) {
        callback('全称已存在');
      }
      callback();
    });
  };

  checkShortName = (rule, value, callback) => {
    if (value === '' || value == null) {
      callback('');
      return;
    }

    const { currentNode, selectedKeys, action } = this.state;

    let params = {
      pathParams: {
        parentId: '',
        id: '',
        rootId: currentNode.rootId,
      },
      queryParams: {
        shortName: value,
      },
    };
    if (action === 'create') {
      params.pathParams.id = '0';
      params.pathParams.parentId = selectedKeys[0];
    } else {
      params.pathParams.id = selectedKeys[0];
      params.pathParams.parentId = currentNode.parentId;
    }

    api.org.checkShortName(params).then(res => {
      if (!res.data) {
        callback('简称已存在');
      }
      callback();
    });
  };

  checkCode = (rule, value, callback) => {
    if (value === '' || value == null) {
      callback('');
      return;
    }

    const { currentNode, selectedKeys, action } = this.state;
    let params = {
      pathParams: {
        id: action === 'create' ? '0' : selectedKeys[0],
        rootId: currentNode.rootId,
      },
      queryParams: {
        code: value,
      },
    };

    api.org.checkCode(params).then(res => {
      if (!res.data) {
        callback('编码已存在');
      }
      callback();
    });
  };

  handleOnInput = e => {
    window.compositionend && (e.target.value = trim(e.target.value));
  };

  render() {
    const { modalVisible, action, selectedKeys, currentNode } = this.state;
    const { form, orgTree, orgType, submitLoading } = this.props;
    return (
      <PageHeaderWrapper title="组织管理">
        <div className={styles.org}>
          <Card className={styles.orgTree}>
            {orgTree.length > 0 && (
              <OrgTree
                ref={this.orgTreeRef}
                treeData={orgTree}
                selectedKeys={selectedKeys}
                onDropdown={this.handleDropdown}
                onMenuClick={this.handleMenuClick}
                onSelect={this.handleTreeSelect}
                onIconClick={this.handleCreateIconClick}
              />
            )}
          </Card>
          <Card className={styles.orgInfo}>
            <OrgInfo data={currentNode} />
          </Card>
        </div>
        <Modal
          maskClosable={false}
          keyboard={false}
          destroyOnClose
          confirmLoading={submitLoading}
          title={action === 'create' ? '添加组织' : '编辑组织'}
          visible={modalVisible}
          onOk={this.okHandle}
          onCancel={this.handleModalVisible}
        >
          <FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="全称">
            {form.getFieldDecorator('name', {
              initialValue: action === 'modify' ? currentNode.name : '',

              rules: [
                { required: true, message: '请输入全称' },
                {
                  pattern: NAME_RULE.PATTERN,
                  message: NAME_RULE.MESSAGE,
                },
                {
                  validator: this.checkName,
                },
              ],
            })(<Input onInput={this.handleOnInput} maxLength={30} />)}
          </FormItem>
          <FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="简称">
            {form.getFieldDecorator('shortName', {
              initialValue: action === 'modify' ? currentNode.shortName : '',
              rules: [
                {
                  required: true,
                  message: '请输入简称',
                  whitespace: true,
                },
                {
                  pattern: NAME_RULE.PATTERN,
                  message: NAME_RULE.MESSAGE,
                },
                {
                  validator: this.checkShortName,
                },
              ],
            })(<Input onInput={this.handleOnInput} maxLength={10} />)}
          </FormItem>
          <FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="编码">
            {form.getFieldDecorator('code', {
              initialValue: action === 'modify' ? currentNode.code : '',
              rules: [
                {
                  required: true,
                  message: '请输入编码',
                  whitespace: true,
                },
                {
                  pattern: CODE_RULE.PATTERN,
                  message: CODE_RULE.MESSAGE,
                },
                {
                  validator: this.checkCode,
                },
              ],
            })(
              <Input onInput={this.handleOnInput} maxLength={15} disabled={action === 'modify'} />
            )}
          </FormItem>
          <FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="类型">
            {form.getFieldDecorator('structType', {
              initialValue:
                action === 'modify'
                  ? currentNode.structType
                  : orgType.length > 1
                    ? orgType[1].code
                    : '',
              rules: [
                {
                  required: true,
                  message: '请选择类型',
                },
              ],
            })(
              <Select style={{ width: '100%' }}>
                {orgType.map(type => {
                  return (
                    <Option key={type.code} value={type.code}>
                      {type.name}
                    </Option>
                  );
                })}
              </Select>
            )}
          </FormItem>
          <FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="描述">
            {form.getFieldDecorator('description', {
              initialValue: action === 'modify' ? currentNode.description : '',
            })(<TextArea maxLength={30} style={{ resize: 'none' }} />)}
          </FormItem>
        </Modal>
      </PageHeaderWrapper>
    );
  }
}

export default Org;
